//
//  ViewController.swift
//  JKCAGradientLayer
//
//  Created by IronMan on 2021/1/31.
//

import UIKit

class ViewController: BaseViewController {
    /// 温度计组件
    lazy var meterView: TemperatureMeter = {
        // 创建并添加温度计组件
        let meter = TemperatureMeter(frame: CGRect(x: 40, y: 80, width: 80, height: 80))
        return meter
    }()
    
    lazy var sliderView: UISlider = {
        let slider = UISlider(frame: CGRect(x: 20, y: meterView.jk.bottom + 20, width: kScreenW - 40, height: 50))
        slider.minimumValue = 0
        slider.maximumValue = 100
        slider.value = 0.0
        // 滑块左右两边槽的颜色
        // 左槽颜色
        slider.minimumTrackTintColor = UIColor.red
        // 右槽颜色
        slider.maximumTrackTintColor = UIColor.green
        slider.addTarget(self, action: #selector(sliderDidChange), for: .valueChanged)
        return slider
    }()
    
    // 彩虹进度条组件
    lazy var rainbowProgress: RainbowProgress = {
        // 创建彩虹进度条
        let frame = CGRect(x: 20, y: 80, width: kScreenW - 40, height:4)
        let progress = RainbowProgress(frame: frame)
        return progress
    }()
    
    lazy var rainbowSliderView: UISlider = {
        let slider = UISlider(frame: CGRect(x: 20, y: rainbowProgress.jk.bottom + 20, width: kScreenW - 40, height: 50))
        slider.minimumValue = 0
        slider.maximumValue = 1
        slider.value = 0.0
        // 滑块左右两边槽的颜色
        // 左槽颜色
        slider.minimumTrackTintColor = UIColor.red
        // 右槽颜色
        slider.maximumTrackTintColor = UIColor.green
        slider.addTarget(self, action: #selector(sliderRainbowDidchange), for: .valueChanged)
        return slider
    }()
    
    lazy var uiSwitch: UISwitch = {
        let switchOff = UISwitch(frame: CGRect(x: 20, y: rainbowSliderView.jk.bottom + 20, width: 50, height: 30))
        switchOff.addTarget(self, action: #selector(switchOn), for: .touchUpInside)
        return switchOff
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .brown
        self.title = "CAGradientLayer"
        self.navigationController?.navigationBar.barTintColor = .brown
        /**
         1，基本介绍
         （1）CAGradientLayer 是 CALayer 的子类，可以理解为一个渐变层。如果使用的是透明0.2的颜色，还可以做到透明渐变。
         （2）CAGradientLayer 目前只能实现线性渐变，还不能实现放射性渐变。
         （3）CAGradientLayer 对象最主要的就是如下 4 个属性：
         colors：颜色数组，定义渐变层的各个颜色。
         locations（可选）：决定每个渐变颜色的终止位置，这些值必须是递增的，数组的长度和 colors 的长度最好一致。
         startPoint（可选）：渲染的起始位置，默认值是：[.5,0]
         endPoint（可选）：渲染的终止位置，默认值是：[.5,1]
         参考链接：https://www.hangge.com/blog/cache/detail_1772.html
         */
        
        headDataArray = ["一、实现渐变色背景", "二、环形渐变进度条、渐变文字", "三、边界渐隐效果", "四、渐变动画：渐变特效、动态光泽文字", "五、渐变动画的实现:（彩虹动画圆环）", "六、渐变动画的实现：彩虹动画进度条"]
        dataArray = [["实现一个双色的渐变背景", "多种颜色的渐变", "封装后的虹渐变层"], ["渐变圆环进度条：下面实现一个用于温度显示的环形进度条。同一般的环形进度条不同，它的进度轨道是有渐变色的。随着温度的升高（进度值增加），颜色从蓝色慢慢渐变到黄色，最终渐变到红色。当进度值改变的时候，进度条前进或后退都有动画效果。", "渐变文字：下面标签文字使用的是渐变色，从上往下由黄色渐变到橙色"], ["tableView的边界渐隐效果"], ["colors 变化动画：背景渐变色就会切换成下一组，同时颜色在改变过程中还会有动画效果", "locations 变化动画，效果图如下\n(1)、下面实现一个动态光泽效果，类似苹果手机过去滑动解锁文字的效果。\n(2)、文字从左到右会有光泽闪过。闪到最右侧时，又从左侧开始重复播放动画。"], ["创建彩虹动画圆环"], ["彩虹动画进度条"]]
    }
}

// MARK:- 六、渐变动画的实现：彩虹动画进度条
extension ViewController {
    
    // MARK: 6.1、彩虹动画进度条
    @objc func test61() {
        /**
          1，效果图
         （1）整个进度条显示的是彩虹色的渐变。而且彩虹条不是固定不动的，会从左往右无限循环轮播移动。
         （2）拖动滑块可以调整进度条的进度。
         （3）点击下方开关可以停止、或者启用彩虹条移动的动画效果。
          2，实现方式
         （1）使用 CAGradientLayer 创建一个从左至右的彩虹色渐变，然后使用 CAShapeLayer 配合 UIBezierPath 绘制一条横线作为它的遮罩，便实现了一个彩虹色的进度条。
         （2）进度条长短百分比我们可以通过 CAShapeLayer 的 strokeEnd 属性来实现。
         （3）动画部分同样使用 CABasicAnimation 实现，将渐变色数组中的最后一个颜色元素移到第一个位置，这样动画播放时看起来就像是渐变层从左往右移动。
         （4）最后在动画结束方法中再重复执行上面的动作，便实现了无限循环轮播移动的动画。
         */
        
        //将彩虹进度条添加到界面上
        self.view.addSubview(rainbowProgress)
        self.view.addSubview(rainbowSliderView)
        self.view.addSubview(uiSwitch)
        
        //开始播放彩虹动画
        rainbowProgress.startAnimating()
        JKAsyncs.asyncDelay(20) {
        } _: {[weak self] in
            guard let weakSelf = self else { return }
            weakSelf.rainbowProgress.removeFromSuperview()
            weakSelf.rainbowSliderView.removeFromSuperview()
            weakSelf.uiSwitch.removeFromSuperview()
        }
    }
    
    // 滑块值改变响应
    @objc func sliderRainbowDidchange(_ sender: UISlider) {
        //设置进度
        self.rainbowProgress.progressValue = CGFloat(sender.value)
    }
    
    @objc func switchOn(on: UISwitch) {
        if uiSwitch.isOn {
            //开始播放彩虹动画
            rainbowProgress.startAnimating()
        }else{
            //停止播放彩虹动画
            rainbowProgress.stopAnimating()
        }
    }
}


// MARK:- 五、渐变动画的实现:（彩虹动画圆环）
extension ViewController {
    
    // MARK: 5.1、创建彩虹动画圆环
    @objc func test51() {
        let rainbowRing = RainbowRing(frame: CGRect(x: 50, y: 80, width: 160, height: 160))
        self.view.addSubview(rainbowRing)
        JKAsyncs.asyncDelay(2) {
        } _: {
            rainbowRing.removeFromSuperview()
        }
    }
}

// MARK:- 四、渐变动画：渐变特效、动态光泽文字
extension ViewController {
    
    // MARK: 4.2、locations 变化动画
    @objc func test42() {
        /**
          1，效果图
         （1）下面实现一个动态光泽效果，类似苹果手机过去滑动解锁文字的效果。
         （2）文字从左到右会有光泽闪过。闪到最右侧时，又从左侧开始重复播放动画。
          2，实现方式
         （1）CAGradientLayer 从左到右使用黑、白、黑渐变。
         （2）动画通过改变 CAGradientLayer 的 locations，从而实现白色部分从左向右移动。
         （3）最后将 UILabel 上的文字作为 CAGradientLayer 的遮罩即可，看起来就像是文字会有动态光泽效果。
         */
        let labelBg = UIView(frame: CGRect(x: 20, y: 120, width: kScreenW - 40, height: 60))
        self.view.addSubview(labelBg)
        
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: kScreenW - 40, height: 60))
        label.text = "我是一只小小鸟"
        label.font = UIFont.systemFont(ofSize: 18)
        label.textColor = .green
        label.textAlignment = .center
        labelBg.addSubview(label)
        
        // 将主视图背景设置为灰色
        self.view.backgroundColor = UIColor.darkGray
        
        // 创建CAGradientLayer对象
        let gradientLayer = CAGradientLayer().gradientLayer(.horizontal, [UIColor.black.cgColor, UIColor.white.cgColor, UIColor.black.cgColor], [0, 0, 0.25])
        
        // 设置其CAGradientLayer对象的frame，并插入view的layer
        gradientLayer.frame = CGRect(x: 0, y: 0, width: labelBg.jk.width, height: labelBg.jk.height)
        
        // 将渐变层添加到文本标签背景上
        labelBg.layer.insertSublayer(gradientLayer, at: 0)
        
        // 添加渐变动画（让白色光泽从左向右移动）
        let gradientAnimation = CABasicAnimation(keyPath: "locations")
        gradientAnimation.fromValue = [0, 0, 0.2]
        gradientAnimation.toValue = [0.8, 1, 1]
        gradientAnimation.duration = 12.5
        // 动画一致重复执行
        gradientAnimation.repeatCount = HUGE
        gradientLayer.add(gradientAnimation, forKey: nil)
        
        // 设置遮罩，让渐变层透过文字显示出来
        labelBg.mask = label
    }
    
    // MARK: 4.1、colors 变化动画
    @objc func test41() {
        // 共三组渐变色
        let colorsSet = [
            [UIColor.yellow.cgColor, UIColor.orange.cgColor],
            [UIColor.cyan.cgColor, UIColor.green.cgColor],
            [UIColor.magenta.cgColor, UIColor.blue.cgColor],
        ]
        
        let testView = UIView(frame: CGRect(x: 20, y: 100, width: kScreenW - 40, height: 60))
        self.view.addSubview(testView)
        
        // 创建CAGradientLayer对象
        let gradientLayer = CAGradientLayer().gradientLayer(.horizontal, colorsSet[0], [0.0, 1.0])
        // 设置其CAGradientLayer对象的frame，并插入view的layer
        gradientLayer.frame = CGRect(x: 0, y: 0, width: testView.jk.width, height: testView.jk.height)
        testView.layer.insertSublayer(gradientLayer, at: 0)
        
        JKAsyncs.asyncDelay(1) {
        } _: { [weak self] in
            guard let weakSelf = self else { return }
            weakSelf.startAnimation(gradientLayer: gradientLayer, currentIndex: 0, nextIndex: 1)
            JKAsyncs.asyncDelay(1) {
            } _: {
                weakSelf.startAnimation(gradientLayer: gradientLayer, currentIndex: 1, nextIndex: 2)
                JKAsyncs.asyncDelay(1) {
                } _: {
                    weakSelf.startAnimation(gradientLayer: gradientLayer, currentIndex: 2, nextIndex: 0)
                    JKAsyncs.asyncDelay(1) {
                    } _: {
                        testView.removeFromSuperview()
                    }
                }
            }
        }
        
    }
    
    func startAnimation(gradientLayer: CAGradientLayer, currentIndex: Int, nextIndex: Int) {
        // 共三组渐变色
        let colorsSet = [
            [UIColor.yellow.cgColor, UIColor.orange.cgColor],
            [UIColor.cyan.cgColor, UIColor.green.cgColor],
            [UIColor.magenta.cgColor, UIColor.blue.cgColor],
        ]
        // 添加渐变动画
        let colorChangeAnimation = CABasicAnimation(keyPath: "colors")
        // colorChangeAnimation.delegate = self
        colorChangeAnimation.duration = 2.0
        colorChangeAnimation.fromValue = colorsSet[currentIndex]
        colorChangeAnimation.toValue = colorsSet[nextIndex]
        colorChangeAnimation.fillMode = CAMediaTimingFillMode.forwards
        // 动画结束后保持最终的效果
        colorChangeAnimation.isRemovedOnCompletion = false
        gradientLayer.add(colorChangeAnimation, forKey: "colorChange")
    }
}

// MARK:- 三、边界渐隐效果
extension ViewController {
    
    // MARK: 3.1、tableView的边界渐隐效果
    @objc func test31() {
        self.navigationController?.pushViewController(TestViewController(), animated: true)
    }
}

// MARK:- 二、环形渐变进度条、渐变文字
extension ViewController {
    
    // MARK: 2.2、渐变文字：下面标签文字使用的是渐变色，从上往下由黄色渐变到橙色
    @objc func test22() {
        /**
         实现原理
         （1）首先分别创建渐变层和文本标签。
         （2）接着将渐变层的 mask 设置为文本标签即可。
         */
        // 创建用于放置文本标签和渐变层的view
        let container = UIView(frame:CGRect(x: 10, y: 100, width: 300, height: 70))
        self.view.addSubview(container)
        
        // 创建文本标签
        let label = UILabel(frame:CGRect(x: 20, y: 0, width: kScreenW - 40, height: 70))
        label.text = "jkironman.com"
        label.font = UIFont.boldSystemFont(ofSize: 30.0)
        container.addSubview(label)
        
        // 创建渐变层
        // 定义渐变的颜色（从黄色渐变到橙色）
        let topColor = UIColor.yellow
        let buttomColor = UIColor.orange
        let gradientColors = [topColor.cgColor, buttomColor.cgColor]
        
        // 定义每种颜色所在的位置
        let gradientLocations: [NSNumber] = [0.0, 1.0]
        
        // 创建CAGradientLayer对象并设置参数
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = gradientColors
        gradientLayer.locations = gradientLocations
        
        // 设置其CAGradientLayer对象的frame，并插入container的layer
        gradientLayer.frame = CGRect(x: 0, y: 0, width: label.jk.width, height: label.jk.height)
        container.layer.insertSublayer(gradientLayer, at: 0)
        
        // 将渐变层的遮罩设置为label
        gradientLayer.mask = label.layer
        
        JKAsyncs.asyncDelay(2) {
        } _: {
            container.removeFromSuperview()
        }
    }
    
    // MARK: 2.1、渐变圆环进度条
    @objc func test21() {
        /*
         1，效果图
         1.1、下面实现一个用于温度显示的环形进度条。同一般的环形进度条不同，它的进度轨道是有渐变色的。随着温度的升高（进度值增加），颜色从蓝色慢慢渐变到黄色，最终渐变到红色。
         1.2、当进度值改变的时候，进度条前进或后退都有动画效果。
         2、实现原理
         2.1、整个进度条组件分成进度条后面的轨道，以及覆盖在上方的具有渐变色的进度条。这里主要讲讲后者的实现。
         2.2、首先使用 CAShapeLayer 配合 UIBezierPath 绘制一个圆弧，这个便是进度条。进度条长短百分比我们可以通过 CAShapeLayer 的 strokeEnd 属性来实现。
         2.3、接着我们使用 CAGradientLayer 绘制一个渐变层。由于 CAGradientLayer 不能顺着弧线进行渐变，只能指定两个点之间进行渐变。所以我们先分别绘制左右两部分的渐变：
         左半部分：颜色从上往下是黄色渐变到蓝色。
         右半部分：颜色从上往下是黄色渐变到红色。
         2.4、最后将渐变层的遮罩设置成前面由 CAShapeLayer 创建的进度弧线，这样一个带有渐变色的进度圆弧就完成了。
         */
        
        self.view.addSubview(meterView)
        self.view.addSubview(sliderView)
        
        JKAsyncs.asyncDelay(7) {
        } _: {[weak self] in
            guard let weakSelf = self else { return }
            weakSelf.meterView.removeFromSuperview()
            weakSelf.sliderView.removeFromSuperview()
        }
    }
    
    @objc func sliderDidChange(slider: UISlider) {
        
        print(CGFloat(slider.value))
        // 设置进度
        meterView.setPercent(percent: CGFloat(slider.value))
        
    }
}

// MARK:- 一、实现渐变色背景
extension ViewController {
    
    // MARK: 1.3、封装后的虹渐变层
    @objc func test13() {
        // 获取彩虹渐变层
        let gradientLayer = CAGradientLayer().rainbowLayer()
        
        let button = UIButton(frame: CGRect(x: 30, y: 150, width: kScreenW - 60, height: 50))
        self.view.addSubview(button)
        
        // 设置其CAGradientLayer对象的frame，并插入button的layer
        gradientLayer.frame = CGRect(x: 0, y: 0, width: button.jk.width, height: button.jk.height)
        button.layer.insertSublayer(gradientLayer, at: 0)
        
        JKAsyncs.asyncDelay(3) {
        } _: {
            button.removeFromSuperview()
        }
    }
    
    // MARK: 1.2、多种颜色的渐变
    @objc func test12() {
        let button = UIButton(frame: CGRect(x: 30, y: 150, width: kScreenW - 60, height: 50))
        self.view.addSubview(button)
        
        //定义渐变的颜色（7种彩虹色）
        let gradientColors = [UIColor.red.cgColor,
                              UIColor.orange.cgColor,
                              UIColor.yellow.cgColor,
                              UIColor.green.cgColor,
                              UIColor.cyan.cgColor,
                              UIColor.blue.cgColor,
                              UIColor.purple.cgColor]
        
        //定义每种颜色所在的位置
        let gradientLocations: [NSNumber] = [0.0, 0.17, 0.33, 0.5, 0.67, 0.83, 1.0]
        
        //创建CAGradientLayer对象并设置参数
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = gradientColors
        gradientLayer.locations = gradientLocations
        
        //设置渲染的起始结束位置（横向渐变）
        gradientLayer.startPoint = CGPoint(x: 0, y: 0)
        gradientLayer.endPoint = CGPoint(x: 1, y: 0)
        
        // 设置其CAGradientLayer对象的frame，并插入button的layer
        gradientLayer.frame = CGRect(x: 0, y: 0, width: button.jk.width, height: button.jk.height)
        button.layer.insertSublayer(gradientLayer, at: 0)
        
        JKAsyncs.asyncDelay(3) {
        } _: {
            button.removeFromSuperview()
        }
    }
    
    // MARK: 1.1、实现一个双色的渐变背景
    @objc func test11() {
        let button = UIButton(frame: CGRect(x: 30, y: 150, width: kScreenW - 60, height: 50))
        self.view.addSubview(button)
        
        // 定义渐变的颜色（从黄色渐变到橙色）
        let topColor = UIColor.yellow
        let buttomColor = UIColor.orange
        let gradientColors = [topColor.cgColor, buttomColor.cgColor]
        
        // 定义每种颜色所在的位置
        let gradientLocations: [NSNumber] = [0.0, 1.0]
        
        // 创建CAGradientLayer对象并设置参数
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = gradientColors
        gradientLayer.locations = gradientLocations
        
        // 设置其CAGradientLayer对象的frame，并插入button的layer
        gradientLayer.frame = CGRect(x: 0, y: 0, width: button.jk.width, height: button.jk.height)
        button.layer.insertSublayer(gradientLayer, at: 0)
        
        JKAsyncs.asyncDelay(3) {
        } _: {
            button.removeFromSuperview()
        }
    }
}
